import Taro from "@tarojs/taro";
import envConfig from "../config/env.config";
import { getToken, getClinicId, clearAllUserInfo } from "./auth.util";

interface RequestOptions {
  url: string;
  method: "GET" | "POST" | "PUT" | "DELETE";
  data?: any;
  timeout?: number;
  header?: any;
  dataType?: "json";
  responseType?: "text" | "arraybuffer";
}

/**
 * 请求管理类 - 简化版
 */
class RequestManager {
  baseURL;
  timeout;
  debug;
  headers;
  onRequest;
  onResponse;
  onRequestError;
  onResponseError;

  constructor(baseURL = null) {
    this.baseURL = baseURL || envConfig.baseURL;
    this.timeout = envConfig.timeout;
    this.debug = envConfig.debug;
    this.headers = {
      clinicId: getClinicId(), // 诊所id
      "Content-Type": "application/json;charset=UTF-8",
    };

    // 拦截器函数
    this.onRequest = null;
    this.onResponse = null;
    this.onRequestError = null;
    this.onResponseError = null;
  }

  /**
   * 设置基础URL
   */
  setBaseURL(baseURL) {
    this.baseURL = baseURL;
  }

  /**
   * 设置默认headers
   */
  setHeaders(headers) {
    this.headers = { ...this.headers, ...headers };
  }

  /**
   * 构建完整URL
   */
  buildUrl(url) {
    if (url.startsWith("http://") || url.startsWith("https://")) {
      return url;
    }
    return `${this.baseURL.replace(/\/$/, "")}/${url.replace(/^\//, "")}`;
  }

  /**
   * 发起请求
   */
  async request<T = any>(options: RequestOptions) {
    const token = getToken() || "";

    // 合并配置
    const config = {
      url: this.buildUrl(options.url),
      method: options.method || "GET",
      data: options.data,
      timeout: options.timeout || this.timeout,
      header: {
        ...this.headers,
        ...options.header,
        token,
      },
      dataType: options?.dataType || "json",
      responseType: options?.responseType || "text",
    };

    // 调试信息
    if (this.debug) {
      console.log("请求配置：", config);
    }

    // 请求拦截器
    if (this.onRequest) {
      try {
        this.onRequest({ request: options });
      } catch (error) {
        if (this.onRequestError) {
          this.onRequestError({ request: options, error });
        }
        throw error;
      }
    }

    try {
      const response = await Taro.request(config);

      // 响应拦截器
      if (this.onResponse) {
        this.onResponse({ request: options, response });
      }

      return response.data as Response<T>;
    } catch (error) {
      // 特殊处理域名白名单错误
      if (error.errMsg && error.errMsg.includes("url not in domain list")) {
        console.error("域名白名单错误，请检查以下几点：");
        console.error(
          '1. 微信开发工具 -> 详情 -> 本地设置 -> 勾选"不校验合法域名"'
        );
        console.error("2. 小程序管理后台添加服务器域名：", config.url);
        console.error("3. 确保生产环境使用HTTPS协议");

        // 显示用户友好的提示
        Taro.showModal({
          title: "网络配置问题",
          content: "请联系开发者配置服务器域名，或在开发工具中关闭域名校验",
          showCancel: false,
        });
      }

      // 响应错误拦截器
      if (this.onResponseError) {
        this.onResponseError({ request: options, error });
      }
      throw error;
    }
  }
}

// 创建请求实例
const requestManager = new RequestManager();

// 配置拦截器示例
requestManager.onRequest = (context) => {
  console.log("请求开始：", context.request);
};

requestManager.onResponse = (context) => {
  console.log("请求成功：", context.response?.data);

  const data = context.response?.data;
  // 处理用户未登录或登录过期的情况
  if (data?.code === "402") {
    // 清空所有用户信息
    clearAllUserInfo();

    // 使用 reLaunch 跳转到登录页
    // reLaunch 会关闭所有页面，打开到应用内的某个页面
    // 这样可以确保页面栈被清空，用户无法返回到需要登录的页面
    Taro.navigateTo({
      url: "/pages/login/login?type=402",
    });
  }
};

requestManager.onRequestError = (context) => {
  console.error("请求错误：", context.error);
  Taro.showToast({
    title: "请求失败",
    icon: "error",
  });
};

requestManager.onResponseError = (context) => {
  console.error("响应错误：", context.error);
  Taro.showToast({
    title: "响应异常",
    icon: "error",
  });
};

// 提取request方法
const { request } = requestManager;

// 导出
export { requestManager, RequestManager, request };

export default requestManager;
